﻿using DevExpress.Utils;
using DevExpress.XtraBars;
using Inaction.Core;
using Inaction.Mapping;
using Inaction.Rule;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Windows.Forms;

namespace Inaction.UI
{
    [ToolboxBitmap(typeof(DevExpress.XtraBars.BarManager))]
    [DesignerCategory("Inaction")]
    [ToolboxItem(true)]
    [Designer("Inaction.UI.BarManagerDesigner", typeof(System.ComponentModel.Design.IDesigner))]
    [ProvideProperty("PopupContextMenu", typeof(System.Windows.Forms.Control))]
    public partial class BarManager : DevExpress.XtraBars.BarManager
    {
        static WaitDialogForm waitDialog = new WaitDialogForm("", "请稍候...") { Visible = false };

        #region 属性
        #region BarManager操作按钮
        private Bar bar;
        private Bar statusBar;

        private BarButtonItem btnQuery;
        internal BarButtonItem BtnQuery
        {
            get
            {
                if (!IsDesignMode && btnQuery == null)
                {
                    btnQuery = (BarButtonItem)Items["btnQuery"];
                }
                return btnQuery;
            }
            set { btnQuery = value; }
        }

        private BarButtonItem btnAddNew;
        internal BarButtonItem BtnAddNew
        {
            get
            {
                if (!IsDesignMode && btnAddNew == null)
                {
                    btnAddNew = (BarButtonItem)Items["btnAddNew"];
                }
                return btnAddNew;
            }
            set { btnAddNew = value; }
        }

        private BarButtonItem btnModify;
        internal BarButtonItem BtnModify
        {
            get
            {
                if (!IsDesignMode && btnModify == null)
                {
                    btnModify = (BarButtonItem)Items["btnModify"];
                }
                return btnModify;
            }
            set { btnModify = value; }
        }

        private BarButtonItem btnDelete;
        internal BarButtonItem BtnDelete
        {
            get
            {
                if (!IsDesignMode && btnDelete == null)
                {
                    btnDelete = (BarButtonItem)Items["btnDelete"];
                }
                return btnDelete;
            }
            set { btnDelete = value; }
        }


        private BarButtonItem btnSave;
        internal BarButtonItem BtnSave
        {
            get
            {
                if (!IsDesignMode && btnSave == null)
                {
                    btnSave = (BarButtonItem)Items["btnSave"];
                }
                return btnSave;
            }
            set { btnSave = value; }
        }

        private BarButtonItem btnCancel;
        internal BarButtonItem BtnCancel
        {
            get
            {
                if (!IsDesignMode && btnCancel == null)
                {
                    btnCancel = (BarButtonItem)Items["btnCancel"];
                }
                return btnCancel;
            }
            set { btnCancel = value; }
        }

        private BarButtonItem btnExit;
        internal BarButtonItem BtnExit
        {
            get
            {
                if (!IsDesignMode && btnExit == null)
                {
                    btnExit = (BarButtonItem)Items["btnExit"];
                }
                return btnExit;
            }
            set { btnExit = value; }
        }

        private BarButtonItem btnImport;
        internal BarButtonItem BtnImport
        {
            get
            {
                if (!IsDesignMode && btnImport == null)
                {
                    btnImport = (BarButtonItem)Items["btnImport"];
                }
                return btnImport;
            }
            set { btnImport = value; }
        }

        private BarButtonItem btnExport;
        internal BarButtonItem BtnExport
        {
            get
            {
                if (!IsDesignMode && btnExport == null)
                {
                    btnExport = (BarButtonItem)Items["btnExport"];
                }
                return btnExport;
            }
            set { btnExport = value; }
        }

        private BarButtonItem btnPrint;
        internal BarButtonItem BtnPrint
        {
            get
            {
                if (!IsDesignMode && btnPrint == null)
                {
                    btnPrint = (BarButtonItem)Items["btnPrint"];
                }
                return btnPrint;
            }
            set { btnPrint = value; }
        }

        private BarButtonItem btnHelp;
        internal BarButtonItem BtnHelp
        {
            get
            {
                if (!IsDesignMode && btnHelp == null)
                {
                    btnHelp = (BarButtonItem)Items["btnHelp"];
                }
                return btnHelp;
            }
            set { btnHelp = value; }
        }

        private BarStaticItem barItemState;

        internal BarStaticItem BarItemState
        {
            get
            {
                if (!IsDesignMode && barItemState == null)
                {
                    barItemState = (BarStaticItem)Items["barItemState"];
                }
                return barItemState;
            }
            set { barItemState = value; }
        }
        private BarStaticItem barItemCurrentDetail;

        internal BarStaticItem BarItemCurrentDetail
        {
            get
            {
                if (!IsDesignMode && barItemCurrentDetail == null)
                {
                    barItemCurrentDetail = (BarStaticItem)Items["barItemCurrentDetail"];
                }
                return barItemCurrentDetail;
            }
            set { barItemCurrentDetail = value; }
        }

        private BarStaticItem barItemText;
        internal BarStaticItem BarItemText
        {
            get
            {
                if (!IsDesignMode && barItemText == null)
                {
                    barItemText = (BarStaticItem)Items["barItemText"];
                }
                return barItemText;
            }
            set { barItemText = value; }
        }
        #endregion

        BarManagerState operateState = BarManagerState.None;
        [Browsable(false)]
        public BarManagerState OperateState
        {
            get { return operateState; }
            private set
            {
                if (operateState == value) return;
                operateState = value;
                SetStateText(EnumDescription.GetDescription(operateState));
                if (OperateStateChanged != null)
                {
                    OperateStateChanged(null, null);
                }
            }
        }
        [Browsable(false)]
        public bool EditMode
        {
            get
            {
                if (MasterBindingInfo == null) return false;
                return operateState == BarManagerState.Modify || MasterBindingInfo.SavableObj != null && MasterBindingInfo.SavableObj.IsDirty;
            }
        }

        #region 数据源

        Collection<BindingInfo> bindingInfos = new Collection<BindingInfo>();
        [Category("Inaction")]
        [Browsable(true)]
        [Description("数据源列表")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Editor(typeof(Inaction.UI.ComponentModel.Design.CollectionEditor), typeof(UITypeEditor))]
        public Collection<BindingInfo> BindingInfos
        {
            get
            {
                if (bindingInfos == null) bindingInfos = new Collection<BindingInfo>();
                return bindingInfos;
            }
            set { bindingInfos = value; }
        }

        private bool showSourceDetail = true;
        [Category("Inaction")]
        [Browsable(true)]
        [DefaultValue(true)]
        [Description("是否显示数据源信息")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public bool ShowSourceDetail
        {
            get { return showSourceDetail; }
            set { showSourceDetail = value; }
        }

        private Int32 masterMaxRecordCount = 0;
        [Category("Inaction")]
        [Browsable(true)]
        [Description("主数据源查询时最大记录条数,为0时将不限记录条数")]
        [DefaultValue(0)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Int32 MasterMaxRecordCount
        {
            get
            {
                if (MasterBindingInfo == null || MasterBindingInfo.TypeIsList == false) return 0;
                return masterMaxRecordCount;
            }
            set { masterMaxRecordCount = value; }
        }

        [NonSerialized]
        BindingInfo masterBindingInfo = null;
        [Category("Inaction")]
        [Browsable(true)]
        [Description("主数据源")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public BindingInfo MasterBindingInfo
        {
            get
            {
                if (masterBindingInfo == null && bindingInfos != null && bindingInfos.Count != 0)
                {
                    masterBindingInfo = bindingInfos[0];
                }
                return masterBindingInfo;
            }
            set
            {
                masterBindingInfo = value;
                InitRootSource();
            }
        }

        [NonSerialized]
        BindingInfo currentBindingInfo = null;
        [Category("Inaction")]
        [Browsable(true)]
        [Description("当前操作的数据源")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public BindingInfo CurrentBindingInfo
        {
            get
            {
                if (currentBindingInfo == null && bindingInfos != null && bindingInfos.Count != 0)
                {
                    currentBindingInfo = MasterBindingInfo;
                }
                return currentBindingInfo;
            }
            set
            {
                if (currentBindingInfo != value)
                {
                    var args = new BindingChangeEventArgs(currentBindingInfo == null ? null : currentBindingInfo.BindingSource, value == null ? null : value.BindingSource);
                    if (CurrentBindingChanging != null)
                    {
                        CurrentBindingChanging(this, args);
                    }
                    currentBindingInfo = value;
                    if (!DesignMode)
                    {
                        ShowCurrentSourceInfo();
                        ApplyFormRules(CurrentBindingInfo);
                    }
                    if (CurrentBindingChanged != null)
                    {
                        CurrentBindingChanged(this, args);
                    }
                }
            }
        }

        [Browsable(false)]
        public Inaction.Core.ISavable CurrentEntity
        {
            get
            {
                if (CurrentBindingInfo == null) return null;
                return CurrentBindingInfo.SavableObj;
            }
        }

        [Browsable(false)]
        public IEntity CurrentBusiness
        {
            get
            {
                if (CurrentBindingInfo == null) return null;
                return CurrentBindingInfo.CurrentBusiness;
            }
        }
        #endregion
        #endregion

        #region 构造
        public BarManager()
        {
            InitializeComponent();
        }

        public BarManager(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
        }
        #endregion

        #region 方法

        private void ShowCurrentSourceInfo()
        {
            if (CurrentBindingInfo == null
                || CurrentBindingInfo.BindingSource == null
                || !CurrentBindingInfo.ItemType.IsSubclassOf(typeof(ModelBase))) return;

            var classInfo = ClassInfo.LoadInfo(currentBindingInfo.ItemType);
            if (ShowSourceDetail)
            {
                BarItemCurrentDetail.Caption = classInfo.DisplayName
                    + "[" + (currentBindingInfo.BindingSource.Position + 1) + "/"
                    + currentBindingInfo.BindingSource.List.Count + "]";
            }
            SetStateText(EditMode ? "编辑" : "浏览");
        }

        internal void InitRootSource()
        {
            if (BindingInfos == null || BindingInfos.Count == 0) return;
            foreach (var bindingInfo in BindingInfos)
            {
                if (bindingInfo.BindingSource == null || string.IsNullOrEmpty(bindingInfo.BindingSource.DataMember))
                {
                    bindingInfo.RootSource = bindingInfo.BindingSource;
                    continue;
                }
                bindingInfo.RootSource = FindRootBindingInfo(bindingInfo);
            }
        }

        private BindingSource FindRootBindingInfo(BindingInfo bindingInfo)
        {
            if (BindingInfos == null || BindingInfos.Count == 0) return null;
            if (bindingInfo == MasterBindingInfo
                || bindingInfo.BindingSource == null
                || string.IsNullOrEmpty(bindingInfo.BindingSource.DataMember))
                return bindingInfo.BindingSource;
            else
            {
                return FindRootBindingInfo(BindingInfos.FirstOrDefault(p => p.BindingSource == bindingInfo.BindingSource.DataSource));
            }
        }

        #endregion
    }

    public enum BarManagerState
    {
        [Description("无")]
        None,
        [Description("浏览")]
        Browse,
        [Description("编辑")]
        Modify
    }
}